package org.bridge.db.dao;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import org.apache.commons.lang.StringUtils;
import org.bridge.db.bean.xml.MapColumn;
import org.bridge.db.bean.xml.MapTable;
import org.bridge.util.xml.XmlUtil;
import org.exolab.castor.mapping.Mapping;
import org.xml.sax.InputSource;

public class DAOUtil {

	private static Map tableMap = new HashMap();

	private static ResourceBundle bundle = ResourceBundle
			.getBundle("db");

	static {
		Mapping mDbObject = new Mapping();
		try {
			// file castor di mapping degli oggetti che mappano il risultato
			// delle query
			InputStream dbObjectInputStream = DAOService.class
					.getResourceAsStream(bundle.getString("castor.dbmapping"));
			mDbObject.loadMapping(new InputSource(dbObjectInputStream));
			InputStream xml = DAOUtil.class.getResourceAsStream(bundle
					.getString("xml.dbmapping"));
			List tables = (List) XmlUtil.unmarshall(mDbObject, xml,
					ArrayList.class);
			if (tableMap == null) {
				tableMap = new HashMap();
			}
			for (Iterator iter = tables.iterator(); iter.hasNext();) {
				MapTable table = (MapTable) iter.next();
				tableMap.put(table.getName(), table);
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	public static Object bind(String tableName, Map map) throws Exception {
		MapTable table = (MapTable) tableMap.get(tableName);
		String className = table.getClassName();

		Class _class = Class.forName(className);
		Object obj = _class.newInstance();
		
		Iterator itKeys = map.keySet().iterator();
		for (; itKeys.hasNext();) {
			String key = (String) itKeys.next();// nome della colonna su db
			Object value = map.get(key);// valore della colonna su db
			// dato il nome della colonna, cerco nell'oggetto table la colonna
			// con dbcColumn=key
			List columns = table.getColumns();
			for (Iterator iter = columns.iterator(); iter.hasNext();) {
				MapColumn column = (MapColumn) iter.next();
				if (column.getDbColumn().equalsIgnoreCase(key)) {
					String methodName = "set"
							+ StringUtils.capitalize(column.getProperty());
					// per il momento considero solo oggetti tipo stringa.
					if (value != null) {
						Method m = obj.getClass().getMethod(methodName,
								new Class[] { value.getClass() });
						m.invoke(obj, new Object[] { value });
					}
				}
			}

		}
		return obj;
	}

}
